use bytes::{Buf, Bytes, BytesMut};
use tools::{
	error::buf_err::{FromBufError, ToBufError},
	types::bufs::{FromBuf, ToBuf},
	utils::byte::split_on,
};

use crate::{CRLF, HEAD_SEPARATOR};

use super::{
	names::{CustHeaderName, HeaderName},
	values::HeaderValue,
	CAN_MULTIPLE_HEADER_NAMES,
};

///描述某一个sip的Header项,即有名称,也有值
///这个结构就是一个存储项
#[derive(Debug)]
struct HeaderItem {
	name: HeaderName,
	//这个值只有当name是Other时才出现
	name_data: Option<CustHeaderName>,
	value: HeaderValue,
}

impl Default for HeaderItem {
	fn default() -> Self {
		Self {
			name: HeaderName::Other,
			name_data: None,
			value: HeaderValue::None,
		}
	}
}

impl HeaderItem {
	#[inline]
	pub(crate) fn new(name: HeaderName, value: HeaderValue) -> Self {
		Self {
			name,
			value,
			..Default::default()
		}
	}

	#[inline]
	pub(crate) fn with_name(name: HeaderName) -> Self {
		Self {
			name,
			..Default::default()
		}
	}
}

impl FromBuf for HeaderItem {
	type From = Bytes;

	fn from_buf_all(mut from: Self::From) -> Result<Self, FromBufError>
	where
		Self: Sized,
	{
		HeaderItem::from_buf(&mut from)
	}

	fn from_buf(from: &mut Self::From) -> Result<Self, FromBufError>
	where
		Self: Sized,
	{
		let buf = split_on(from, b':');
		let name = HeaderName::from_buf_all(&buf)?;

		let mut slf = Self::with_name(name);
		if slf.name == HeaderName::Other {
			slf.name_data = Some(CustHeaderName::from_buf_all(buf)?);
		}
		slf.value = HeaderValue::from_buf(from)?;

		Ok(slf)
	}
}

///描述一组sip头信息
#[derive(Debug)]
pub struct Headers {
	inner: Vec<HeaderItem>,
}

impl Default for Headers {
	fn default() -> Self {
		Self::new()
	}
}

impl Headers {
	pub(crate) fn set_content_length(&mut self, len: usize) {
		let value = HeaderValue::with_int(len as i32);
		for it in self.inner.iter_mut() {
			if it.name == HeaderName::ContentLength {
				it.value = value;
				return;
			}
		}

		self.inner.push(HeaderItem {
			name: HeaderName::ContentLength,
			value,
			name_data: None,
		});
	}

	pub(crate) fn new() -> Self {
		Self {
			inner: Vec::with_capacity(25),
		}
	}

	#[inline]
	pub(crate) fn is_empty(&self) -> bool {
		self.inner.is_empty()
	}

	/// 将一个值加入一个头信息数据内.
	/// 此时无论内部是否有相同的值
	#[inline]
	pub(crate) fn insert<T>(&mut self, name: HeaderName, value: T)
	where
		T: Into<HeaderValue>,
	{
		if CAN_MULTIPLE_HEADER_NAMES.contains(&name) {
			self.inner.push(HeaderItem::new(name, value.into()));
			return;
		} else {
			self.replace_or_insert(name, value);
		}
	}

	/// 将一个值加入一个头信息数据内.
	/// 如果存在值,将替换掉已经存在的内容
	#[inline]
	pub(crate) fn replace_or_insert<T>(&mut self, name: HeaderName, value: T)
	where
		T: Into<HeaderValue>,
	{
		match self.inner.iter_mut().find(|it| it.name == name) {
			Some(it) => it.value = value.into(),
			None => self.inner.push(HeaderItem::new(name, value.into())),
		}
	}
}

impl ToBuf for Headers {
	type Target = BytesMut;

	#[inline]
	fn write_to(&self, target: &mut Self::Target) -> Result<(), ToBufError> {
		for it in self.inner.iter() {
			it.name.write_to(target)?;
			target.extend_from_slice(HEAD_SEPARATOR);
			it.value.write_to(target)?;
			target.extend_from_slice(CRLF);
		}

		//头结束符
		target.extend_from_slice(CRLF);
		Ok(())
	}
}

impl FromBuf for Headers {
	type From = Bytes;

	fn from_buf_all(mut from: Self::From) -> Result<Self, FromBufError>
	where
		Self: Sized,
	{
		Self::from_buf(&mut from)
	}

	#[inline]
	fn from_buf(from: &mut Self::From) -> Result<Self, FromBufError>
	where
		Self: Sized,
	{
		let mut headers = Self::new();

		// 判断是否完全结束,或者到了头部的底
		while !from.is_empty() {
			headers.inner.push(HeaderItem::from_buf(from)?);

			if from[0..2] == *CRLF {
				from.advance(2);
				break;
			}
		}

		Ok(headers)
	}
}
